# -*- coding: UTF-8 -*-
#
#       support.py
#       
#       Copyright 2009-2011 Giuseppe Penone <giuspen@gmail.com>
#       
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.

import gtk, os
import cons


def get_node_hierarchical_name(dad, tree_iter):
   """Get the Node Hierarchical Name"""
   hierarchical_name = dad.treestore[tree_iter][1]
   father_iter = dad.treestore.iter_parent(tree_iter)
   while father_iter:
      hierarchical_name = dad.treestore[father_iter][1] + "--" + hierarchical_name
      father_iter = dad.treestore.iter_parent(father_iter)
   return hierarchical_name.replace("/", "-")

def windows_cmd_prepare_path(filepath):
   """Prepares a Path to be digested by windows command line"""
   if not cons.CHAR_DQUOTE in filepath: return cons.CHAR_DQUOTE + filepath + cons.CHAR_DQUOTE
   elif not cons.CHAR_SQUOTE in filepath: return cons.CHAR_SQUOTE + filepath + cons.CHAR_SQUOTE
   return None

def dialog_file_save_as(filename=None, filter_pattern=None, filter_name=None, curr_folder=None, parent=None):
   """The Save file as dialog, Returns the retrieved filepath or None"""
   chooser = gtk.FileChooserDialog(title=_("Save File as"),
                                   action=gtk.FILE_CHOOSER_ACTION_SAVE,
                                   buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK) )
   if parent != None:
      chooser.set_transient_for(parent)
      chooser.set_property("modal", True)
      chooser.set_property("destroy-with-parent", True)
      chooser.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
   else: chooser.set_position(gtk.WIN_POS_CENTER)
   if curr_folder == None or os.path.isdir(curr_folder) == False:
      chooser.set_current_folder(os.path.expanduser('~'))
   else:
      chooser.set_current_folder(curr_folder)
   if filename != None:
      chooser.set_current_name(filename)
   if filter_pattern != None:
      filter = gtk.FileFilter()
      filter.set_name(filter_name)
      filter.add_pattern(filter_pattern)
      chooser.add_filter(filter)
   if chooser.run() == gtk.RESPONSE_OK:
      filepath = chooser.get_filename()
      chooser.destroy()
      return filepath
   else:
      chooser.destroy()
      return None

def dialog_file_select(filter_pattern=None, filter_name=None, curr_folder=None, parent=None):
   """The Select file dialog, Returns the retrieved filepath or None"""
   chooser = gtk.FileChooserDialog(title = _("Select File"),
                                   action=gtk.FILE_CHOOSER_ACTION_OPEN,
                                   buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) )
   if parent != None:
      chooser.set_transient_for(parent)
      chooser.set_property("modal", True)
      chooser.set_property("destroy-with-parent", True)
      chooser.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
   else: chooser.set_position(gtk.WIN_POS_CENTER)
   if curr_folder == None or os.path.isdir(curr_folder) == False:
      chooser.set_current_folder(os.path.expanduser('~'))
   else:
      chooser.set_current_folder(curr_folder)
   if filter_pattern != None:
      filter = gtk.FileFilter()
      filter.set_name(filter_name)
      filter.add_pattern(filter_pattern)
      chooser.add_filter(filter)
   if chooser.run() == gtk.RESPONSE_OK:
      filepath = chooser.get_filename()
      chooser.destroy()
      return filepath
   else:
      chooser.destroy()
      return None
   
def dialog_folder_select(curr_folder=None, parent=None):
   """The Select folder dialog, returns the retrieved folderpath or None"""
   chooser = gtk.FileChooserDialog(title = _("Select Folder"),
                                   action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
                                   buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) )
   if parent != None:
      chooser.set_transient_for(parent)
      chooser.set_property("modal", True)
      chooser.set_property("destroy-with-parent", True)
      chooser.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
   else: chooser.set_position(gtk.WIN_POS_CENTER)
   if curr_folder == None or os.path.isdir(curr_folder) == False:
      chooser.set_current_folder(os.path.expanduser('~'))
   else:
      chooser.set_current_folder(curr_folder)
   if chooser.run() == gtk.RESPONSE_OK:
      folderpath = chooser.get_filename()
      chooser.destroy()
      return folderpath
   else:
      chooser.destroy()
      return None
   
def dialog_question(message, parent=None):
   """The Question dialog, returns True if the user presses OK"""
   dialog = gtk.MessageDialog(flags=gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
                              type=gtk.MESSAGE_QUESTION,
                              buttons=gtk.BUTTONS_OK_CANCEL,
                              message_format=message)
   if parent != None:
      dialog.set_transient_for(parent)
      dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
   else: dialog.set_position(gtk.WIN_POS_CENTER)
   dialog.set_title(_("Question"))
   if dialog.run() == gtk.RESPONSE_OK:
      dialog.destroy()
      return True
   else:
      dialog.destroy()
      return False

def dialog_info(message, parent=None):
   """The Info dialog"""
   dialog = gtk.MessageDialog(flags=gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
                              type=gtk.MESSAGE_INFO,
                              buttons=gtk.BUTTONS_OK,
                              message_format=message)
   if parent != None:
      dialog.set_transient_for(parent)
      dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
   else: dialog.set_position(gtk.WIN_POS_CENTER)
   dialog.set_title(_("Info"))
   dialog.run()
   dialog.destroy()

def dialog_warning(message, parent=None):
   """The Warning dialog"""
   dialog = gtk.MessageDialog(flags=gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
                              type=gtk.MESSAGE_WARNING,
                              buttons=gtk.BUTTONS_OK,
                              message_format=message)
   if parent != None:
      dialog.set_transient_for(parent)
      dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
   else: dialog.set_position(gtk.WIN_POS_CENTER)
   dialog.set_title(_("Warning"))
   dialog.run()
   dialog.destroy()
   
def dialog_error(message, parent=None):
   """The Error dialog"""
   dialog = gtk.MessageDialog(flags=gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
                              type=gtk.MESSAGE_ERROR,
                              buttons=gtk.BUTTONS_OK,
                              message_format=message)
   if parent != None:
      dialog.set_transient_for(parent)
      dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
   else: dialog.set_position(gtk.WIN_POS_CENTER)
   dialog.set_title(_("Error"))
   dialog.run()
   dialog.destroy()

def dialog_selnode_selnodeandsub_alltree(father_win):
   """Dialog to select between the Selected Node/Selected Node + Subnodes/All Tree"""
   dialog = gtk.Dialog(title=_("Involved Nodes"),
                               parent=father_win,
                               flags=gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
                               buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
                               gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) )
   dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
   radiobutton_selnode = gtk.RadioButton(label=_("Selected Node Only"))
   radiobutton_selnodeandsub = gtk.RadioButton(label=_("Selected Node and Subnodes"))
   radiobutton_alltree = gtk.RadioButton(label=_("All the Tree"))
   radiobutton_selnodeandsub.set_group(radiobutton_selnode)
   radiobutton_alltree.set_group(radiobutton_selnode)
   content_area = dialog.get_content_area()
   content_area.pack_start(radiobutton_selnode)
   content_area.pack_start(radiobutton_selnodeandsub)
   content_area.pack_start(radiobutton_alltree)
   def on_key_press_enter_dialog(widget, event):
      if gtk.gdk.keyval_name(event.keyval) == "Return":
         button_box = dialog.get_action_area()
         buttons = button_box.get_children()
         buttons[0].clicked() # first is the ok button
   dialog.connect("key_press_event", on_key_press_enter_dialog)
   content_area.show_all()
   response = dialog.run()
   if radiobutton_selnode.get_active(): ret_val = 1
   elif radiobutton_selnodeandsub.get_active(): ret_val = 2
   else: ret_val = 3
   dialog.destroy()
   if response != gtk.RESPONSE_ACCEPT: ret_val = 0
   return ret_val

def set_bookmarks_menu_items(inst):
   """Set Bookmarks Menu Items"""
   bookmarks_menu = inst.ui.get_widget("/MenuBar/BookmarksMenu").get_submenu()
   for menu_item in inst.bookmarks_menu_items:
      bookmarks_menu.remove(menu_item)
   menu_item = gtk.SeparatorMenuItem()
   menu_item.show()
   bookmarks_menu.append(menu_item)
   inst.bookmarks_menu_items = [menu_item]
   for node_id_str in inst.bookmarks:
      if not long(node_id_str) in inst.nodes_names_dict: continue
      menu_item = gtk.ImageMenuItem(inst.nodes_names_dict[long(node_id_str)])
      menu_item.set_image(gtk.image_new_from_stock("Red Cherry", gtk.ICON_SIZE_MENU))
      menu_item.connect("activate", select_bookmark_node, node_id_str, inst)
      menu_item.show()
      bookmarks_menu.append(menu_item)
      inst.bookmarks_menu_items.append(menu_item)

def set_menu_items_recent_documents(inst):
   """Set Recent Documents menu items on Menu and Toolbar"""
   inst.recent_menu_1 = gtk.Menu()
   inst.recent_menu_2 = gtk.Menu()
   for target in [1, 2]:
      for filepath in inst.recent_docs:
         menu_item = gtk.ImageMenuItem(filepath)
         menu_item.set_image(gtk.image_new_from_stock("gtk-open", gtk.ICON_SIZE_MENU))
         menu_item.connect("activate", open_recent_document, filepath, inst)
         menu_item.show()
         if target == 1: inst.recent_menu_1.append(menu_item)
         else: inst.recent_menu_2.append(menu_item)
   # main menu
   recent_menuitem = gtk.ImageMenuItem(_("_Recent Documents"))
   recent_menuitem.set_image(gtk.image_new_from_stock("gtk-open", gtk.ICON_SIZE_MENU))
   recent_menuitem.set_tooltip_text(_("Open a Recent CherryTree Document"))
   recent_menuitem.set_submenu(inst.recent_menu_1)
   inst.ui.get_widget("/MenuBar/FileMenu").get_submenu().insert(recent_menuitem, 9)
   # toolbar
   menu_toolbutton = gtk.MenuToolButton("gtk-open")
   menu_toolbutton.set_tooltip_text(_("Open a CherryTree Document"))
   menu_toolbutton.set_arrow_tooltip_text(_("Open a Recent CherryTree Document"))
   menu_toolbutton.set_menu(inst.recent_menu_2)
   menu_toolbutton.connect("clicked", inst.file_open)
   inst.ui.get_widget("/ToolBar").insert(menu_toolbutton, 9)

def add_recent_document(inst, filepath):
   """Add a Recent Document if Needed"""
   if not filepath in inst.recent_docs:
      inst.recent_docs.append(filepath)
      for target in [1, 2]:
         menu_item = gtk.ImageMenuItem(filepath)
         menu_item.set_image(gtk.image_new_from_stock("gtk-open", gtk.ICON_SIZE_MENU))
         menu_item.connect("activate", open_recent_document, filepath, inst)
         menu_item.show()
         if target == 1: inst.recent_menu_1.append(menu_item)
         else: inst.recent_menu_2.append(menu_item)

def open_recent_document(menu_item, filepath, dad):
   """A Recent Document was Requested"""
   if os.path.isfile(filepath): dad.filepath_open(filepath)
   else:
      dialog_error(_("The Document %s was Not Found") % filepath, dad.window)
      menu_item.hide()
      try: dad.recent_docs.remove(filepath)
      except: pass

def select_bookmark_node(menu_item, node_id_str, dad):
   """Select a Node in the Bookmarks List"""
   node_iter = dad.get_tree_iter_from_node_id(long(node_id_str))
   if node_iter: dad.treeview_safe_set_cursor(node_iter)

def bookmarks_handle(dad):
   """Handle the Bookmarks List"""
   dialog = gtk.Dialog(title=_("Handle the Bookmarks List"),
                       parent=dad.window,
                       flags=gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
                       buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
                       gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) )
   dialog.set_default_size(500, 400)
   dialog.set_transient_for(dad.window)
   dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
   liststore = gtk.ListStore(str, str, str)
   for node_id_str in dad.bookmarks:
      liststore.append(["Red Cherry", dad.nodes_names_dict[long(node_id_str)], node_id_str])
   treeview = gtk.TreeView(liststore)
   treeview.set_headers_visible(False)
   treeview.set_reorderable(True)
   treeview.set_tooltip_text(_("Sort with Drag and Drop, Delete with the Delete Key"))
   treeviewselection = treeview.get_selection()
   def on_key_press_liststore(widget, event):
      keyname = gtk.gdk.keyval_name(event.keyval)
      if keyname == "Delete":
         model, tree_iter = treeviewselection.get_selected()
         if tree_iter: model.remove(tree_iter)
   treeview.connect('key_press_event', on_key_press_liststore)
   renderer_pixbuf = gtk.CellRendererPixbuf()
   renderer_text = gtk.CellRendererText()
   column = gtk.TreeViewColumn()
   column.pack_start(renderer_pixbuf, False)
   column.pack_start(renderer_text, True)
   column.set_attributes(renderer_pixbuf, stock_id=0)
   column.set_attributes(renderer_text, text=1)
   treeview.append_column(column)
   scrolledwindow = gtk.ScrolledWindow()
   scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
   scrolledwindow.add(treeview)
   content_area = dialog.get_content_area()
   content_area.pack_start(scrolledwindow)
   content_area.show_all()
   response = dialog.run()
   temp_bookmarks = []
   tree_iter = liststore.get_iter_first()
   while tree_iter != None:
      temp_bookmarks.append(liststore[tree_iter][2])
      tree_iter = liststore.iter_next(tree_iter)
   dialog.destroy()
   if response != gtk.RESPONSE_ACCEPT: return False
   dad.bookmarks = temp_bookmarks
   set_bookmarks_menu_items(dad)
   return True

def set_object_highlight(inst, obj_highl):
   """Set the Highlight to obj_highl only"""
   if inst.highlighted_obj:
      inst.highlighted_obj.drag_unhighlight()
      inst.highlighted_obj = None
   if obj_highl:
      obj_highl.drag_highlight()
      inst.highlighted_obj = obj_highl
